#pragma once

#include <map>
#include <vector>
#include <list>
#include <windows.h>
#include "EngineObject.h"
#include "EnginePointer.h"

class IEngineSystem;

typedef struct GUIDCmp : binary_function<GUID, GUID, bool>
{
	bool operator()(const GUID& g1, const GUID& g2) const
	{
		return memcmp(& g1,& g2, sizeof(GUID) ) < 0; 
	}
} GUIDCmp;

class SystemCollection : public EngineObject
{
public:
	SystemCollection(void);
	~SystemCollection(void);

	EnginePointer<IEngineSystem> getSystem(GUID systemIdentifier);
	void addSystem(EnginePointer<IEngineSystem>& system);
	void GenerateLevels();
	int getNumberOfLevels();
	list<EnginePointer<IEngineSystem>>::iterator begin();
	list<EnginePointer<IEngineSystem>>::iterator end();
	list<EnginePointer<IEngineSystem>>::iterator levelBegin(int level);
	list<EnginePointer<IEngineSystem>>::iterator levelEnd(int level);

	AUTO_SIZE;
private:
	map<GUID, EnginePointer<IEngineSystem>, GUIDCmp> systems;
	list<EnginePointer<IEngineSystem>> systemsList;
	vector<list<EnginePointer<IEngineSystem>>> systemsLevelList;
	UINT numberOfLevels;

	// Level Generation
	map<GUID, int, GUIDCmp> lengthMap;
	int GetLongestPathLength(EnginePointer<IEngineSystem> system);
};
